/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.mindlistening.webui;

import com.googlecode.mindlistening.audio.AudioRecorder;
import com.googlecode.mindlistening.audio.SimpleAudioRecorder;
import com.googlecode.mindlistening.events.DiarizeConfigEvent;
import com.googlecode.mindlistening.events.RecordingFinishedEvent;
import com.googlecode.mindlistening.events.ScreenGrabFinishEvent;
import com.googlecode.mindlistening.events.ScreenGrabStartEvent;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sound.sampled.LineUnavailableException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.bushe.swing.event.EventBus;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator.Feature;
import org.codehaus.jackson.map.ObjectMapper;
import org.mortbay.jetty.Request;

/**
 *
 * @author ryan
 */
public class AudioInternalJsonHandler implements InternalJsonHandler {

    AudioRecorder recorder;
    File recordingInProgressDir;
    File recordingCompleteDir;
    File currentFile;
    String currentRecordingId;
    String currentRecordingDB;
    boolean diarizeCurrentRecording;

    public AudioInternalJsonHandler(File recordingInProgressDir, File recordingCompleteDir, AudioRecorder recorder) {
        this.recordingInProgressDir = recordingInProgressDir;
        this.recordingCompleteDir = recordingCompleteDir;
        this.recorder = recorder;
    }


    @Override
    public void handle(String path, HttpServletRequest request, HttpServletResponse response, int i) throws IOException, ServletException {
        Map<String, Object> json = new HashMap<String, Object>();
            if (path.endsWith("/start")) {
                if (recorder.isRecording()) {
                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                    json.put("status", "already_recording");
                } else {
                    String timestamp = System.currentTimeMillis() + "";
                    currentRecordingId = getRecordingId(request);
                    currentRecordingDB = request.getParameter("db");
                    currentFile = new File(recordingInProgressDir, currentRecordingId);
                    currentFile.mkdir();
                    try {
                        recorder.startRecording(currentFile, "default", 0);
                        String framerate = request.getParameter("framerate");
                        if (StringUtils.isNotEmpty(framerate)) {
                            long framerate_l = Long.parseLong(framerate);
                            ScreenGrabStartEvent start = new ScreenGrabStartEvent(currentFile, framerate_l);
                            EventBus.publish(start);
                        }
                        diarizeCurrentRecording = false;
                        String diarize = request.getParameter("diarize");
                        if (StringUtils.isNotEmpty(diarize)) {
                           diarizeCurrentRecording = Boolean.parseBoolean(diarize);
                        }
                        DiarizeConfigEvent dce = new DiarizeConfigEvent(diarizeCurrentRecording);
                        EventBus.publish(dce);
                        json.put("status", "recording");
                        json.put("recording_id", currentRecordingId);

                        response.setStatus(HttpServletResponse.SC_OK);
                    } catch (Exception ex) {
                        Logger.getLogger(AudioInternalJsonHandler.class.getName()).log(Level.SEVERE, null, ex);
                        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                        json.put("status", "failed");
                        json.put("error", ex.getMessage());
                    }
                    
                }

            } else if (path.endsWith("/stop") ) {
                String lastRecordingId = currentRecordingId;
                String lastRecordingDb = currentRecordingDB;
                long duration = recorder.stopRecording();
                EventBus.publish(new ScreenGrabFinishEvent());
                EventBus.publish(new RecordingFinishedEvent(lastRecordingDb, lastRecordingId, duration, diarizeCurrentRecording));
                response.setStatus(HttpServletResponse.SC_OK);
                json.put("status", "stopped");
                json.put("duration", duration);
            } else if (path.endsWith("/status")) {
                if (this.recorder.isRecording()) {
                    json.put("status", "recording");
                    json.put("recording_id", currentRecordingId);
                } else {
                    json.put("status", "stopped");
                }
            }
            response.setContentType("application/json");

            String jsonp = request.getParameter("callback");
            if (jsonp != null) {
                JsonFactory factory = new JsonFactory().configure(Feature.AUTO_CLOSE_TARGET, false);
                ObjectMapper mapper = new ObjectMapper();
                Writer w = response.getWriter();
                w.write(jsonp + "(");
                mapper.writeValue(factory.createJsonGenerator(w), json);
                w.write(")");
            } else {
                ObjectMapper mapper = new ObjectMapper();
                mapper.writeValue(response.getWriter(), json);
            }


            ((Request)request).setHandled(true);
    }




    protected String getRecordingId(HttpServletRequest request) throws IOException {
        return request.getParameter("id");
    }

}
